home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
msdos
/
viewers
/
grabsc11
/
tsr.asm
< prev
next >
Wrap
Assembly Source File
|
1990-11-28
|
13KB
|
708 lines
;
;Routines to set up a program as TSR, by hooking the keyboard interrupt
;locally and testing the scancodes against given scancode hot key.
;This module was tested in TINY model only.
;This module is based on "MSDOS encyclopedia" snap.asm example pp 360-380.
;You may want to refer to that reference for more information.
;Unlike the original article we assume here DOS 3.1 or above.
;
; Defined functions (see also TSR.H):
;
; 1. int HookKbdInterrupt(void (*Func)(), unsigned int ScanCode);
; Hook the keyboard interrupts so that Func is called if ScanCode is
; detected. Returns:
; 0 - everything O.K..
; 1 - already installed.
; 2 - can not install (int 02fh ID is in use).
;
; Compile as "tasm tsr.asm/mx"
;
; Written by Gershon Elber, Sep. 1990
;
dosseg
public _HookKbdInterrupt
public _InstalledTSRSegment
.model tiny ;select tiny model
.code ;TC-compatible code segment
MultiplexID equ 'G' ;Hopefully unique int 2FH ID value.
TSRStackSize equ 0100h ;Resident stack size in bytes.
KB_FLAG equ 017h
KBIns equ 080h
KBCaps equ 040h
KBNum equ 020h
KBScroll equ 010h
KBAlt equ 008h
KBCtl equ 004h
KBLeft equ 002h
KBRight equ 001h
TRUE equ -1
FALSE equ 0
;****************************************************************************
;Hook to activate the TSR application routine. *
;****************************************************************************
DoTSRApplication proc near
;
push ds
push ax
;
push cs
pop ds
mov ax,cs
;
mov PrevSP,sp ;Save previous SS:SP and set ours.
mov PrevSS,ss
mov ss,ax
mov sp,offset StackTop
;
push es
push bx
push cx
push dx
push si
push di
push bp
;
cld
;
;Set up the interrupt trapping routines.
;
mov cx,NTrap
mov si,offset StartTrapList
DoTSR1: lodsb
;
mov byte ptr [si],FALSE ;Zero the trap flag.
;
push ax
mov ah,035h ;Get old interrupt vector.
int 021h ;/
mov [si+1],bx ;And save it.
mov [si+3],es ;/
pop ax
;
mov dx,[si+5] ;ds:dx hold out interrupt handler.
mov ah,025h ;Set new interrupt vector.
int 021h ;/
;
add si,007
loop DoTSR1
;
mov ax,03300h ;Disable break during disk I/O.
int 021h ; |
mov PrevBreak,dl ; |
xor dl,dl ; |
mov ax,03301h ; |
int 021h ;/
;
;Preserve previous extrended error information.
;
push ds
xor bx,bx
mov ah,059h ;Get extrended error info
int 021h
mov cs:PrevExtErrDs,ds
pop ds
mov PrevExtErrAx,ax
mov PrevExtErrBx,bx
mov PrevExtErrCx,cx
mov PrevExtErrDx,dx
mov PrevExtErrSi,si
mov PrevExtErrDi,di
mov PrevExtErrEs,es
;
mov ah,051h ;Get current PSP
int 021h ; |
mov PrevPSP,bx ;/
;
mov bx,TSRPSP ;Set our PSP
mov ah,050h ; |
int 021h ;/
;
mov ah,02fh ;Get DTA address
int 021h ; |
mov PrevDTAoffs,bx ; |
mov PrevDTAseg,es ;/
;
push ds
mov ds,TSRPSP
mov dx,00080h ;ds:dx is new DTA.
mov ah,01ah ;Set DTA address.
int 021h ;/
pop ds
;
mov byte ptr cs:ActiveTSR,TRUE
;
mov ax,00e07h ;Do some noise
int 010h ;/
;
call word ptr [FuncAddr]
;
mov ax,00e07h ;Do some noise
int 010h ;/
mov byte ptr cs:ActiveTSR,FALSE
;
push ds
lds dx,PrevDTA ;Restore DTA.
mov ah,01ah ;Set DTA address.
int 021h ;/
pop ds
;
mov bx,PrevPSP ;Restore PSP.
mov ah,050h ;Set PSP address.
int 021h ;/
;
mov dx,offset PrevExtErrInfo ;Restore extended error information
mov ax,05d0ah ; |
int 021h ;/
;
mov dl,PrevBreak ;Restore previous MSDOS break status.
mov ax,03301h ; |
int 021h ;/
;
mov cx,NTrap
mov si,offset StartTrapList
push ds
;
DoTSR5: lods byte ptr cs:[si] ;Restore previous traps.
lds dx,cs:[si+1]
mov ah,025h
int 021h
add si,00007h
loop DoTSR5
;
pop ds
;
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop es
;
mov ss,PrevSS
mov sp,PrevSP
;
pop ax
pop ds
;
mov byte ptr cs:HotFlag,FALSE
;
ret
;
DoTSRApplication endp
;
;****************************************************************************
;This Function verifies we are not in DOS. *
;****************************************************************************
VerifyDOSState proc near
;
push ds
push bx
push ax
;
lds bx,cs:ErrorModeAddr
mov ah,[bx]
;
lds bx,cs:InDosAddr
mov al,[bx]
;
xor bx,bx
cmp bl,cs:InISR28
;
rcl bl,01h
;
cmp bx,ax
;
pop ax
pop bx
pop ds
;
ret
;
VerifyDOSState endp
;****************************************************************************
;This Function verifies we are not in BIOS. *
;****************************************************************************
VerifyIntState proc near
;
push ax
;
mov ax,000001011b ;RR = 1, RIS = 1.
out 020h,al
jmp short VerInt1 ;Buy some time.
VerInt1:in al,020h
cmp ah,al
jc short VerInt2 ;Hardware interrupt is been serviced?
;
xor al,al
cmp al,cs:InISR5
jc short VerInt2
;
cmp al,cs:InISR9
jc short VerInt2
;
cmp al,cs:InISR10
jc short VerInt2
;
cmp al,cs:InISR13
;
VerInt2:pop ax
;
ret
;
VerifyIntState endp
;****************************************************************************
;This Function verifies we are not in DOS/BIOS. *
;****************************************************************************
VerifyTSRState proc near
;
ror cs:HotFlag,1 ;Hot key has been pressed?
cmc
jc short VerTSR1
;
ror cs:ActiveTSR,1 ;Are we in the middle of serving our TSR?
jc short VerTSR1
;
call VerifyDOSState
jc short VerTSR1
;
call VerifyIntState
;
VerTSR1:ret
;
VerifyTSRState endp
;****************************************************************************
;The following routines monitor activity in different interrupt vectors. *
;****************************************************************************
ISR5 proc far
;
inc cs:InISR5
;
pushf
cli
call cs:PrevISR5
;
dec cs:InISR5
;
iret
;
ISR5 endp
;****************************************************************************
ISR8 proc far
;
pushf
cli
call cs:PrevISR8
;
cmp cs:InISR8,0
jne short ISR8b ;Exit if already in this handler.
;
inc cs:InISR8
;
sti
call VerifyTSRState
jc short ISR8a
;
call DoTSRApplication
;
ISR8a: dec cs:InISR8
;
ISR8b: iret
;
ISR8 endp
;****************************************************************************
ISR9 proc far
;
push ds
push ax
push bx
;
push cs
pop ds
;
in al,060h
;
pushf
cli
call cs:PrevISR9
;
mov ah,ds:InISR9
or ah,ds:HotFlag
jnz short ISR9d
;
inc ds:InISR9
sti
;
cmp ds:HotSeqLen,0
je short ISR9a
;
mov bx,ds:HotIndex
cmp al,[bx+HotSequence]
jne short ISR9b
;
inc bx
cmp bx,ds:HotSeqLen
jb short ISR9c
;
ISR9a: push ds
mov ax,0040h
mov ds,ax
mov al,ds:[KB_FLAG]
pop ds
;
and al,ds:HotKbMask
cmp al,ds:HotKBFlag
jne short ISR9c
;
mov byte ptr ds:HotFlag,TRUE
;
ISR9b: xor bx,bx
;
ISR9c: mov ds:HotIndex,bx
dec ds:InISR9
;
ISR9d: pop bx
pop ax
pop ds
;
iret
;
ISR9 endp
;****************************************************************************
ISR10 proc far
;
inc cs:InISR10
;
pushf
cli
call cs:PrevISR10
;
dec cs:InISR10
;
iret
;
ISR10 endp
;****************************************************************************
ISR13 proc far
;
inc cs:InISR13
;
pushf
cli
call cs:PrevISR13
;
pushf
dec cs:InISR13
popf
;
sti
ret 2
;
ISR13 endp
;****************************************************************************
ISR1B proc far
;
mov byte ptr cs:Trap1B,TRUE
;
iret
;
ISR1B endp
;****************************************************************************
ISR23 proc far
;
mov byte ptr cs:Trap23,TRUE
;
iret
;
ISR23 endp
;****************************************************************************
ISR24 proc far
;
mov byte ptr cs:Trap24,TRUE
;
mov al,3 ;fail the MSDOS call.
;
iret
;
ISR24 endp
;****************************************************************************
ISR28 proc far
;
pushf
cli
call cs:PrevISR28
;
cmp cs:InISR28,0
jne short ISR28b
;
inc cs:InISR28
;
call VerifyTSRState
jc short ISR28a
;
call DoTSRApplication
;
ISR28a: dec cs:InISR28
;
ISR28b: iret
;
ISR28 endp
;****************************************************************************
ISR2F proc far
;
cmp ah,MultiplexID
je short ISR2Fa
;
jmp cs:PrevISR2F
;
ISR2Fa: test al,al
jnz short ISR2Fb
;
mov al,0ffh
mov bx,cs ;Return the installed TSR segment.
;
ISR2Fb: iret
;
ISR2F endp
;****************************************************************************
; Data section: *
;****************************************************************************
.data? ;TC-comp. uninitialized data segment.
_InstalledTSRSegment dw ? ;If already installed - segment addr.
ErrorModeAddr dd ? ;MSDOS ErrorMode flag address.
InDosAddr dd ? ;MSDOS InDOS flag address.
;
NISR dw (EndISRList-StartISRList) / 8 ;# of installed ISRs.
;
StartISRList db 005h ;Int number.
InISR5 db FALSE
PrevISR5 dd ?
dw offset ISR5
;
db 008h ;Int number.
InISR8 db FALSE
PrevISR8 dd ?
dw offset ISR8
;
db 009h ;Int number.
InISR9 db FALSE
PrevISR9 dd ?
dw offset ISR9
;
db 010h ;Int number.
InISR10 db FALSE
PrevISR10 dd ?
dw offset ISR10
;
db 013h ;Int number.
InISR13 db FALSE
PrevISR13 dd ?
dw offset ISR13
;
db 028h ;Int number.
InISR28 db FALSE
PrevISR28 dd ?
dw offset ISR28
;
db 02fh ;Int number.
InISR2f db FALSE
PrevISR2f dd ?
dw offset ISR2f
;
EndISRList label byte
;
TSRPSP dw ? ;Resident PSP
PrevPSP dw ? ;Previous PSP
PrevSP dw ? ;Previous SS:SP
PrevSS dw ?
;
PrevBreak db ?
;
PrevDTA label dword
PrevDTAoffs dw ?
PrevDTAseg dw ?
;
HotIndex dw 0 ;Index of next scancode in seq.
HotSeqLen dw EndHotSeq-HotSequence ;Length of hot keys seq.
;
HotSequence db ? ;Hot sequence of scan codes.
EndHotSeq label byte
;
HotKBFlag db ?
HotKBMask db (KBIns or KBCaps or KBNum or KBScroll) xor 0ffh
HotFlag db FALSE
;
ActiveTSR db FALSE
;
DOSVersion label word
db ? ;Minor version number.
MajorVersion db ? ;Major version number.
;
;Data used by the TSR application trapping.
;
PrevExtErrInfo label byte
PrevExtErrAx dw ?
PrevExtErrBx dw ?
PrevExtErrCx dw ?
PrevExtErrDx dw ?
PrevExtErrSi dw ?
PrevExtErrDi dw ?
PrevExtErrDs dw ?
PrevExtErrEs dw ?
dw 3 dup(0)
;
NTrap dw (EndTrapList-StartTrapList) / 8
;
StartTrapList db 01bh
Trap1B db FALSE
PrevISR1B dd ?
dw offset ISR1B
;
db 023h
Trap23 db FALSE
PrevISR23 dd ?
dw offset ISR23
;
db 024h
Trap24 db FALSE
PrevISR24 dd ?
dw offset ISR24
;
EndTrapList label byte
;
FuncAddr dw ? ;Address of TSR application.
;****************************************************************************
; Stack to be used by the resident section (in code segment...): *
;****************************************************************************
.code
db TSRStackSize dup("Stack ")
StackTop label word
;****************************************************************************
; Transient code - called only once in initialization process. *
;****************************************************************************
.code
;****************************************************************************
;This Function hooks the keyboard interrupt handler to ours, and save *
;the requested scancode and function to call for it. *
;Returns 0 in ax if O.k. otherwise error code (see header of this file. *
;****************************************************************************
_HookKbdInterrupt proc near
;
push bp
mov bp,sp
push bx
push cx
push dx
push si
push di
push es
push ds
;
mov ax,[bp+6] ;Get scan code to compare with.
mov byte ptr HotKBFlag,al ; |
mov byte ptr HotSequence,ah ;/
;
mov ax,[bp+4] ;Get Func address.
mov word ptr FuncAddr,ax ;/
;
mov ax,cs
mov ds,ax
;
mov TSRPSP,cs
;
mov ah,030h ;Get dos version.
int 021h ; |
xchg ah,al ; |
mov DosVersion,ax ;/
;
mov ah,MultiplexID ;Verify its not already installed.
xor al,al ; |
int 02fh ; |
test al,al ; |
jz short Hook3 ; |
cmp al,0ffh ; |
jne short Hook2 ; |
mov ax,00001h ; | Already installed.
mov _InstalledTSRSegment,bx ; | Save installed TSR segment.
jmp short Hook9 ; |
Hook2: mov ax,00002h ; | Can not install.
jmp short Hook9 ;/
;
Hook3: mov ah,034h ;Get InDOS address.
int 021h ; |
mov word ptr InDOSAddr,bx ; |
mov word ptr InDOSAddr+2,es ; |
dec bx ; | Error mode is just before it.
mov word ptr ErrorModeAddr,bx ; |
mov word ptr ErrorModeAddr+2,es ;/
;
mov cx,NISR
mov si,offset StartISRList
Hook4: lodsb
;
push ax
mov ah,035h ;Get old interrupt vector.
int 021h ; |
mov [si+1],bx ; | And save it
mov [si+3],es ;/
pop ax
;
push ds
mov dx,[si+5]
push cs
pop ds
mov ah,025h ;Set our interrupt vector
int 021h ;/
pop ds
add si,00007h
loop Hook4
;
mov es,cs:[02ch] ;Free the environment.
mov ah,049h ; |
int 021h ;/
;
xor ax,ax
;
Hook9: pop ds
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop bp
;
ret
;
_HookKbdInterrupt endp
end